package com.paul.security;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by dell on 2016/3/23.
 * 在使用集群时，使用缓存来共享session
 * 如果不是集群环境不注入此类即可
 * 本列使用的是redis
 */
public class RedisSessionDAO extends AbstractSessionDAO {

    private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);


    /**
     * shiro-redis的session对象前缀
     */
    private String keyPrefix = "shiro_redis_session:";

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionid=this.generateSessionId(session);
        this.assignSessionId(session,sessionid);
        this.saveSession(session);
        return sessionid;
    }

    @Override
    protected Session doReadSession(Serializable serializable) {
        return this.getSession(serializable);
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        this.saveSession(session);
    }

    @Override
    public void delete(Session session) {
        this.deleteSession(session.getId());
    }

    @Override
    public Collection<Session> getActiveSessions() {

        return this.getAllSessions();
    }

    /**
     * 保存session到redis
     */
    public void saveSession(Session session){
        if(session!=null&&session.getId()!=null){
            String key=getRedisSessionKey(session.getId());
            long timeout=session.getTimeout()/1000;
            redisTemplate.opsForValue().set(key,session);
        }
    }
    public void deleteSession(Serializable id){
        if(id==null){
            logger.error("sessionid不能为空");
            return ;
        }
        redisTemplate.delete(this.getRedisSessionKey(id));
    }
    /**
     * 根据sessionid获取session
     * @param id
     * @return
     */
    public Session getSession(Serializable id){
        if(id==null){
            logger.error("sessionid不能为空");
            return null;
        }
        Session session=null;
        String key=this.getRedisSessionKey(id);
        session=(Session)redisTemplate.opsForValue().get(key);
        return session;
    }

    /**
     * 得到所有的缓存session
     * @return
     */
    public Collection<Session> getAllSessions(){
        Set<Session> sessions=new HashSet<Session>();
        Set<String> bytesKeys=redisTemplate.keys(this.keyPrefix.toString()+"*");
        if(bytesKeys!=null){
            for(String key:bytesKeys){
                Session session=(Session) redisTemplate.opsForValue().get(key);
                sessions.add(session);
            }
        }
        return  sessions;
    }
    /**
     * 获取redis中的session key
     *
     * @param sessionId
     * @return
     */
    private String getRedisSessionKey(Serializable sessionId) {
        return this.keyPrefix + sessionId;
    }
}
